package com.zm.openapi.client.test;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

public class HttpRequestUtil {
    private static final Logger logger = LoggerFactory.getLogger(HttpRequestUtil.class);

	public static String sendPost(String url, String param, Map<String, Object> headers) {
	    return sendPost(url, param, headers, 30000, 300000);
	}
	
	public static String sendPost(String url, String param, Map<String, Object> headers, 
	        int connectTimeout, int readTimeout) {
	    String result = "";
	    try {
	        if (url.contains("https://")) {
	            HttpsURLConnection.setDefaultHostnameVerifier(new HttpRequestUtil().new NullHostNameVerifier());
	            SSLContext sc = SSLContext.getInstance("TLS");
	            sc.init(null, trustAllCerts, new SecureRandom());
	            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
	        }
	        
	        
	        URL urlObject = new URL(url);
	        // 打开链接
	        HttpURLConnection conn = (HttpURLConnection) urlObject.openConnection();
	        if(MapUtils.isNotEmpty(headers)) {
	            for (Map.Entry<String, Object> header : headers.entrySet()) {
	                conn.setRequestProperty(header.getKey(), String.valueOf(header.getValue()));
	            }
	        }
	        
	        
	        // 设置参数
	        conn.setRequestMethod("POST"); // 设置POST方式连接
	        conn.setDoOutput(true); // 需要输出
	        conn.setDoInput(true); // 需要输入
	        conn.setUseCaches(false); // 不允许缓存
	        // 设置请求属性
	        conn.setRequestProperty("accept", "*/*");
	        conn.setRequestProperty("connection", "Keep-Alive");
	        conn.setRequestProperty("Charset", "UTF-8");
	        // 连接超时30秒
	        conn.setConnectTimeout(connectTimeout);
	        // 读取超时300秒
	        conn.setReadTimeout(readTimeout);
	        
	        // 建立输入流，向指向的URL传入参数
	        DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
	        dos.writeBytes(param);
	        dos.flush();
	        dos.close();
	        // 获得响应状态
	        int resultCode = conn.getResponseCode();
	        if (HttpURLConnection.HTTP_OK == resultCode) {
	            StringBuffer sb = new StringBuffer();
	            String readLine = new String();
	            BufferedReader responseReader = new BufferedReader(
	                    new InputStreamReader(conn.getInputStream(), "UTF-8"));
	            while ((readLine = responseReader.readLine()) != null) {
	                sb.append(readLine).append("\n");
	            }
	            responseReader.close();
	            result = sb.toString();
	        } else {
	            JSONObject err = new JSONObject();
	            err.put("code", 0);
	            err.put("msg", resultCode + " " + conn.getResponseMessage());
	            result = err.toJSONString();
	        }
	        
	        return result;
	    } catch (Exception e) {
	        logger.error("http 请求异常 ", e);
	        return null;
	    }
	}

	static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	}};

	public class NullHostNameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String arg0, SSLSession arg1) {
			return true;
		}
	}

}